#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "esm6800_drivers.h"

int GPIO_OutEnable(int fd, unsigned int dwEnBits);
int GPIO_OutDisable(int fd, unsigned int dwDisBits);
int GPIO_OpenDrainEnable(int fd, unsigned int dwODBits);
int GPIO_OutSet(int fd, unsigned int dwSetBits);
int GPIO_OutClear(int fd, unsigned int dwClearBits);
int GPIO_PinState(int fd, unsigned int* pPinState);

int main(int argc, char** argv)
{
	int				fd;
	int				rc;
	int				i1;
	unsigned int	dwPinState;
	int             numOfGPIOs = 32;		//there are 32 GPIOs in EM335X

	printf("Driver esm6800_gpio test\n");

	fd = open("/dev/esm6800_gpio", O_RDWR);
	printf("open file = %d\n", fd);
	
	dwPinState = 0xffffffff;				// read states of all bits
	rc = GPIO_PinState(fd, &dwPinState);
	if(rc < 0)
	{
		printf("GPIO_PinState::failed %d\n", rc);
		return rc;
	}
	printf("PinState = 0x%08x\n", dwPinState);
	sleep(1);									//delay 1 second

	rc = GPIO_OutEnable(fd, 0xffffffff);	//set all GPIO as output
	if(rc < 0)
	{
		printf("GPIO_OutEnable::failed %d\n", rc);
		return rc;
	}

	//clear GPIO bit one by one
	for(i1 = 0; i1 < numOfGPIOs; i1++)
	{
		rc = GPIO_OutClear(fd, (1 << i1));
		if(rc < 0)
		{
			printf("GPIO_OutClear::failed %d\n", rc);
			return rc;
		}
		/*dwPinState = 0xffffffff;				// read states of all bits
		rc = GPIO_PinState(fd, &dwPinState);
		if(rc < 0)
		{
			printf("GPIO_PinState::failed %d\n", rc);
			return rc;
		}
		printf("PinState = 0x%08x\n", dwPinState);*/
		sleep(1);									//delay 1 second
	}

	//set GPIO bit one by one
	for(i1 = 0; i1 < numOfGPIOs; i1++)
	{
		rc = GPIO_OutSet(fd, (1 << i1));
		if(rc < 0)
		{
			printf("GPIO_OutSet::failed %d\n", rc);
			return rc;
		}
		/*dwPinState = 0xffffffff;				// read states of all bits
		rc = GPIO_PinState(fd, &dwPinState);
		if(rc < 0)
		{
			printf("GPIO_PinState::failed %d\n", rc);
			return rc;
		}
		printf("PinState = 0x%08x\n", dwPinState);*/
		sleep(1);									//delay 1 second
	}
	
	close(fd);
	printf("close file\n");
	return 0;
}

int GPIO_OutEnable(int fd, unsigned int dwEnBits)
{
	int 				rc;
	struct double_pars	dpars;

	dpars.par1 = ESM6800_GPIO_OUTPUT_ENABLE;		// 0
	dpars.par2 = dwEnBits;

	rc = write(fd, &dpars, sizeof(struct double_pars));
	return rc;
}

int GPIO_OutDisable(int fd, unsigned int dwDisBits)
{
	int 				rc;
	struct double_pars	dpars;

	dpars.par1 = ESM6800_GPIO_OUTPUT_DISABLE;	// 1
	dpars.par2 = dwDisBits;

	rc = write(fd, &dpars, sizeof(struct double_pars));
	return rc;
}

int GPIO_OutSet(int fd, unsigned int dwSetBits)
{
	int 				rc;
	struct double_pars	dpars;

	dpars.par1 = ESM6800_GPIO_OUTPUT_SET;	// 2
	dpars.par2 = dwSetBits;

	rc = write(fd, &dpars, sizeof(struct double_pars));
	return rc;
}

int GPIO_OutClear(int fd, unsigned int dwClearBits)
{
	int 				rc;
	struct double_pars	dpars;

	dpars.par1 = ESM6800_GPIO_OUTPUT_CLEAR;	// 3
	dpars.par2 = dwClearBits;

	rc = write(fd, &dpars, sizeof(struct double_pars));
	return rc;
}

int GPIO_PinState(int fd, unsigned int* pPinState)
{
	int 				rc;
	struct double_pars	dpars;

	dpars.par1 = ESM6800_GPIO_INPUT_STATE;	// 5
	dpars.par2 = *pPinState;

	rc = read(fd, &dpars, sizeof(struct double_pars));
	if(!rc)
	{
		*pPinState = dpars.par2;
	}
	return rc;
}



